/*
 * Copyright (c) 2022 FuZhou Lockzhiner Electronic Co., Ltd. All rights reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <math.h>
#include "los_task.h"
#include "ohos_init.h"
#include "lz_hardware.h"
#include "iot_gpio.h"
#include "iot_errno.h"
#include "los_swtmr.h"
#include <stdint.h>
#include "iot_pwm.h"
#include <stdbool.h>  // 添加对bool类型的支持


// 声明来自 adc_key.c 的函数
extern float adc_get_voltage(void);
extern bool IsChildLockEnabled(void);

/* 定义ADC的通道号 */
#define ADC_CHANNEL         5

/* 定义ADC初始化的结构体 */
static DevIo m_adcKey = {
    .isr =   {.gpio = INVALID_GPIO},
    .rst =   {.gpio = INVALID_GPIO},
    .ctrl1 = {.gpio = GPIO0_PC5, .func = MUX_FUNC1, .type = PULL_NONE, .drv = DRIVE_KEEP, .dir = LZGPIO_DIR_IN, .val = LZGPIO_LEVEL_KEEP},
    .ctrl2 = {.gpio = INVALID_GPIO},
};

/* 定义晾衣架控制变量 */
#define LIFT_UP         1
#define LIFT_DOWN       2
#define Drying          3
#define Open_Light      4
#define Turn_off_Light  5
#define LIFT_UP_STOP    6
#define LIFT_DOWN_STOP  7
#define STOP            0

static int lift_state = STOP; // 0: stopped, 1: lifting up, 2: lifting down，3：drying

/* 记录按键状态 */
static int key_state = 0; // 0: no key pressed, 1: K1, 2: K2, 3: K3, 4: K4
static int prev_key_state = 0; // 用于记录上一次按键状态
static int key_click_count[5] = {0}; // 记录每个按键的点击次数
/***************************************************************
* 函数名称: adc_dev_init
* 说    明: 初始化ADC
* 参    数: 无
* 返 回 值: 0为成功，反之为失败
***************************************************************/
static unsigned int adc_dev_init()
{
    unsigned int ret = 0;
    uint32_t *pGrfSocCon29 = (uint32_t *)(0x41050000U + 0x274U);
    uint32_t ulValue;

    ret = DevIoInit(m_adcKey);
    if (ret != LZ_HARDWARE_SUCCESS)
    {
        printf("%s, %s, %d: ADC Key IO Init fail\n", __FILE__, __func__, __LINE__);
        return __LINE__;
    }
    ret = LzSaradcInit();
    if (ret != LZ_HARDWARE_SUCCESS) {
        printf("%s, %s, %d: ADC Init fail\n", __FILE__, __func__, __LINE__);
        return __LINE__;
    }

    /* 设置saradc的电压信号，选择AVDD */
    ulValue = *pGrfSocCon29;
    ulValue &= ~(0x1 << 4);
    ulValue |= ((0x1 << 4) << 16);
    *pGrfSocCon29 = ulValue;
    
    return 0;
}

/***************************************************************
* 函数名称: adc_process
* 说    明: ADC采集循环任务
* 参    数: 无
* 返 回 值: 无
***************************************************************/
static void adc_process()
{
    float voltage;

    /* 初始化adc设备 */
    adc_dev_init();
    
    while (1)
    {
        // 检查童锁状态
        if (IsChildLockEnabled()) {
            printf("童锁已启用，按键被锁定\n");
            LOS_Msleep(1000);
            continue;
        }

        /* 获取电压值 - 使用adc_key.c中的函数 */
        voltage = adc_get_voltage();

        /* 根据电压值判断按键状态 */
        if (voltage > 3.200){
            key_state = 0;
        }else if (voltage > 1.600) {
            key_state = 4; // K4 pressed
            printf("K4 pressed\n");
        } else if (voltage > 1.000) {
            key_state = 3; // K3 pressed
            printf("K3 pressed\n");
        } else if (voltage > 0.500) {
            key_state = 2; // K2 pressed
            printf("K2 pressed\n");
        } else if (voltage > 0.004) {
            key_state = 1; // K1 pressed
            printf("K1 pressed\n");
        } else {
            key_state = 0; // No key pressed
        }

        /* 处理按键状态 */
        if (key_state != prev_key_state)
        {
            key_click_count[key_state]++; // 增加当前按键的点击次数
            switch (key_state)
            {
            case 1: // K1 pressed
                if (key_click_count[key_state] % 2 == 1){
                    lift_state = LIFT_UP;
                }else{
                    lift_state = LIFT_UP_STOP;
                }
                break;
            case 2: // K2 pressed
                if (key_click_count[key_state] % 2 == 1){
                    lift_state = LIFT_DOWN;
                }
                else{
                    lift_state = LIFT_DOWN_STOP;
                }
                break;
            case 3: // K3 pressed
                lift_state = Drying;
                break;
            case 4: // K4 pressed
                if (key_click_count[key_state] % 2 == 1){
                    lift_state = Open_Light;
                }
                else{
                    lift_state = Turn_off_Light;
                }
                break;
            default:
                // 无操作
                lift_state = STOP;
                break;
            }
            prev_key_state = key_state; // 更新上一次按键状态
        }

        /* 控制晾衣架状态 */
        switch (lift_state) {
            case LIFT_UP:
                // 控制晾衣架上升
                printf("Lifting Up\n");
                // 这里添加控制晾衣架上升的代码
                motorup();
                break;
            case LIFT_UP_STOP:
                // 控制晾衣架停止上升
                printf("Stop Lifting Up\n");
                // 这里添加停止晾衣架上升的代码
                motorstop();
                break;
            case LIFT_DOWN:
                // 控制晾衣架下降
                printf("Lifting Down\n");
                // 这里添加控制晾衣架下降的代码
                motordown();
                break;
            case LIFT_DOWN_STOP:
                // 控制晾衣架停止下降
                printf("Stop Lifting Down\n");
                // 这里添加停止晾衣架下降的代码
                motorstop7();
                break;
            case Drying:
                // 重置烘干操作
                printf("Drying\n");
                // 这里添加烘干操作的代码
                fan_heater_demo_init(2,30);
                lift_state = STOP;
                break;
            case Open_Light:
                // 控制开灯的代码
                printf("Opening Light\n");
                // 这里添加操作的代码
                init_light_on();
                break;
            case Turn_off_Light:
                // 控制关灯
                printf("Turn off Light\n");
                // 这里添加操作的代码
                init_light_off();
                break;
            case STOP:
                // 无操作
                printf("No operation\n");
                break;
            default:
                // 无操作
                break;
        }

        /* 睡眠1秒 */
        usleep(1000000);
    }
}

/***************************************************************
* 函数名称: smart_drying_racks_example
* 说    明: 开机自启动调用函数
* 参    数: 无
* 返 回 值: 无
***************************************************************/
void smart_drying_racks_example()
{
    unsigned int thread_id;
    TSK_INIT_PARAM_S task = {0};
    unsigned int ret = LOS_OK;

    task.pfnTaskEntry = (TSK_ENTRY_FUNC)adc_process;
    task.uwStackSize = 2048;
    task.pcName = "adc process";
    task.usTaskPrio = 24;
    ret = LOS_TaskCreate(&thread_id, &task);
    if (ret != LOS_OK)
    {
        printf("Falied to create task ret:0x%x\n", ret);
        return;
    }
}

APP_FEATURE_INIT(smart_drying_racks_example);